﻿#include "downloader.h"
#include <QDir>
#include "ycompress.h"
#include <QDebug>
#include "enetwork.h"
#include <QSslConfiguration>
#include "mylogger.h"

using namespace ns_yht;

Downloader::Downloader(QNetworkAccessManager *manage, const QString &appDir, bool isBackup) : m_manage(manage)
{
    m_isRunning = false;
    m_appDir = appDir;
    m_isBackup = isBackup;
}

#if 0
void Downloader::start(ModelFile *model)
{
    m_isRunning = true;
    m_modelFile = model;

    QString fullPath = model->filePath + "/";
#ifdef __linux__
    if (m_modelFile->downloadUrl.right(4).toLower() == ".zip")
        fullPath += "../";
#endif
    QDir dir(fullPath);
    if (!dir.exists())
        dir.mkpath(fullPath);

    QStringList strs = model->downloadUrl.split('/');
    QString fileName = fullPath + strs.last();
    fileName += ".tmp";
    m_file = new QFile(fileName);
    m_file->open(QIODevice::WriteOnly);

    const QByteArray url = model->downloadUrl.toUtf8();

    if (url == "")
    {
        emit finished(false);
        return;
    }

    m_request.setUrl(QUrl::fromUserInput(url));

    // 没有如下设置有时会导致：QNetworkReply::SslHandshakeFailedError "SSL 握手失败"
    QSslConfiguration config = QSslConfiguration::defaultConfiguration();
    // config.setProtocol(QSsl::AnyProtocol);
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    m_request.setSslConfiguration(config);

    m_reply = m_manage->get(m_request);
    if (m_reply != nullptr)
    {
        connect(m_reply, &QNetworkReply::finished, this, &Downloader::onFinished);
        connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onDownloadProgress(qint64, qint64)));
        connect(m_reply, SIGNAL(readyRead()), this, SLOT(onDownloadReadyRead()));
    }
    else
        emit finished(false);
}
#endif

void Downloader::start(const QString &fileName, const QString &url)
{
    m_isRunning = true;
    m_remoteFileName = fileName;

    QString fullPath = m_appDir + "/";
#ifdef __linux__
    if (fileName.right(4).toLower() == ".zip")
        fullPath += "../";
#endif
    QDir dir(fullPath);
    if (!dir.exists())
        dir.mkpath(fullPath);

    // QStringList strs = model->downloadUrl.split('/');
    QString fullFileName = fullPath + fileName;
    fullFileName += ".tmp";
    m_file = new QFile(fullFileName);
    m_file->open(QIODevice::WriteOnly);

    QByteArray downloadUrl = (url == "" ? QString("http://restapi.ehanghai.cn/xxyc-api/appmanager/download/%1").arg(fileName).toUtf8() : url.toUtf8());

    if (downloadUrl == "")
    {
        emit finished(false);
        return;
    }
    if (downloadUrl.startsWith("https"))
    {
        downloadUrl.remove(4, 1);
    }
    if (GLOG)
        GLOG->info("start download......");
    m_request.setUrl(QUrl::fromUserInput(downloadUrl));

    // 没有如下设置有时会导致：QNetworkReply::SslHandshakeFailedError "SSL 握手失败"
    QSslConfiguration config = QSslConfiguration::defaultConfiguration();
    config.setProtocol(QSsl::AnyProtocol);
    config.setPeerVerifyMode(QSslSocket::VerifyNone);
    m_request.setSslConfiguration(config);
    m_request.setRawHeader("token", TOKEN.toUtf8());

    m_reply = m_manage->get(m_request);
    if (m_reply != nullptr)
    {
        connect(m_reply, &QNetworkReply::finished, this, &Downloader::onFinished);
        connect(m_reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(onDownloadProgress(qint64, qint64)));
        connect(m_reply, SIGNAL(readyRead()), this, SLOT(onDownloadReadyRead()));
    }
    else
        emit finished(false);
}

void Downloader::onFinished()
{
    m_file->close();
    if (m_reply->error() != QNetworkReply::NoError || m_file->size() == 0)
    {
        if (GLOG)
            GLOG->info(QString("m_reply->error()=============error: %1   errorString: %2").arg(m_reply->error()).arg(m_reply->errorString()).toStdString());
        m_reply->deleteLater();
        emit finished(false);
        m_isRunning = false;
        return;
    }
    m_reply->deleteLater();
    QString filename = m_file->fileName().left(m_file->fileName().length() - 4);
    // 如果数据文件被占用，会失败
    if (m_isBackup)
    {
        QString backupFileName = m_appDir + "backup/" + m_remoteFileName;
        QFile::remove(backupFileName);
        QFile::rename(filename, backupFileName);
    }
    else
        QFile::remove(filename);
    m_file->rename(filename);

    QTextCodec *fileNameCodec = QTextCodec::codecForName("GBK");
    QString fullPath = m_appDir + "/";

    if (m_remoteFileName.right(4).toLower() == ".zip")
    {
#ifdef __linux__
        fullPath += "../";
#endif
        QStringList list = YCompress::extractDirWithRename(m_file->fileName(), fileNameCodec, fullPath);
        if (list.count() == 0)
        {
            emit finished(false);
            m_isRunning = false;
            return;
        }
    }
    if (GLOG)
        GLOG->info("download and extract finished.");
    emit finished(true);
    m_isRunning = false;
}

void Downloader::onDownloadProgress(qint64 a, qint64 b)
{
    emit downloadProgress(a, b);
}

void Downloader::onDownloadReadyRead()
{
    m_file->write(m_reply->readAll());
}
